import { T_task } from '@/obj/class/base/task/index';
import * as echarts from 'echarts';
import { getConfig, getValidChartConfig, ifs, N_cBaseChart, Tsrv } from './config';

class T_cmd {
  // 主组件箱
  private compBox: ifs.I_compBox;

  // 主组件ID
  private compID: string;

  private task: T_task = new T_task(5000);

  // 主组件实例
  private self: N_cBaseChart.cBaseChart;

  // 图表配置
  public chartConfig: N_cBaseChart.ChartConfig;

  // ECharts实例
  public chartInstance: any = null;

  public chartData: N_cBaseChart.ChartData[] = [];

  // 定时器引用
  private refreshTimer: any = null;

  // 当前数据
  private currentData: any = null;

  // 主组件created里初始化
  public init(self: N_cBaseChart.cBaseChart, compBoxInfo: ifs.I_compBoxInfo) {
    this.self = self;
    this.compBox = compBoxInfo.TcompBox;
    this.compID = compBoxInfo.compID;

    this.initConfig();

    // 初始化配置
    this.chartConfig = getValidChartConfig(self.config);
  }

  /**
   * 设置系列可见性
   */
  public setSeriesVisibility(visibility: boolean[]): void {
    // 设置chartData中对应系列的active状态
    visibility.forEach((isVisible, index) => {
      if (this.chartData[index]) {
        this.chartData[index].active = isVisible;
      }
    });
    this.updateChartOptions();
  }

  /**
   * 生成随机数据模拟API响应
   */
  private generateRandomData(): any {
    const now = new Date();

    // 为每个数据源生成随机数据
    this.chartData.forEach((item, index) => {
      for (let index = 0; index < 5; index++) {
        const baseValue = 50 + index; // 不同系列有不同的基准值
        const randomValue = baseValue + Math.floor(Math.random() * 30) - 15;
        item.values.push({
          t: new Date(now.getTime() - (index * 1000)).toISOString(),
          v: randomValue,
          label: '0'
        });
      }
    });


  }

  private initConfig() {
    const config = getConfig();
    Object.keys(config).forEach(key => {
      this.chartData.push({
        code: key,
        active: true,
        values: config[key].d.sort((a, b) => new Date(a.t).getTime() - new Date(b.t).getTime())
      })
    })
  }

  /**
   * 初始化图表
   */
  public initChart(): void {
    if (!this.self) {
      console.error('组件未挂载，无法初始化图表');
      return;
    }

    try {
      // 销毁现有实例
      // this.dispose();

      // 创建新的ECharts实例
      // const chartDom = this.self.$el.querySelector('.chart-container');
      const chartDom = this.self.$refs.chartContainer as HTMLDivElement;
      if (!chartDom) {
        console.error('找不到图表容器');
        return;
      }

      this.chartInstance = echarts.init(chartDom, this.chartConfig.chart.theme);

      // 设置初始选项
      this.updateChartOptions();

      // 启动数据刷新任务
      this.startDataRefreshTask();

      // 监听窗口大小变化
      window.addEventListener('resize', this.handleResize.bind(this));

    } catch (error) {
      console.error('初始化图表失败:', error);
    }
  }

  /**
   * 更新图表数据
   */
  public updateData(newData: any): void {
    if (!newData) return;

    this.currentData = newData;

    // 处理新数据并更新chartData
    // this.processAndUpdateChartData(newData);

    // 只更新series数据，而不是整个配置
    this.updateSeriesDataOnly();
  }

  /**
   * 处理并更新chartData
   */
  private processAndUpdateChartData(newData: any): void {
    // 根据newData更新this.chartData
    Object.keys(newData).forEach(key => {
      const dataItem = this.chartData.find(item => item.code === key);
      if (dataItem && newData[key].d) {
        dataItem.values = newData[key].d.sort((a, b) =>
          new Date(a.t).getTime() - new Date(b.t).getTime()
        );
      }
    });
  }

  /**
   * 只更新series数据（优化性能）
   */
  private updateSeriesDataOnly(): void {
    if (!this.chartInstance) return;

    const xAxisData = this.getXAxisData();
    const seriesData = this.generateSeriesData(this.chartConfig.series, xAxisData)
      .filter((s, index) => this.chartData[index]?.active !== false);


    // 只更新series数据，保持其他配置不变
    this.chartInstance.setOption({
      xAxis: {
        data: xAxisData
      },
      series: seriesData.map(s => ({
        data: s.data
      }))
    }, {
      notMerge: false, // 使用merge模式，只更新变化的部分
      lazyUpdate: true // 延迟更新，提高性能
    });
  }

  public dispose() {
    if (this.chartInstance) {
      this.chartInstance.dispose();
      this.chartInstance = null;
    }
  }

  /**
   * 刷新图表数据
   */
  public refresh(): void {
    if (this.chartConfig.data.source.type === 'scada-api') {
      // 模拟API请求，使用随机数据
      setTimeout(() => {
        const randomData = this.generateRandomData();
        this.updateData(randomData);
      }, 300); // 模拟网络延迟
    } else if (this.chartConfig.data.source.type === 'database') {
      this.fetchDataFromDatabase();
    } else {
      // 静态数据也支持随机更新
      this.generateRandomData();

      // this.updateData();
      this.updateSeriesDataOnly();
    }
  }

  /**
   * 调整图表尺寸
   */
  public resize(): void {
    if (this.chartInstance) {
      this.chartInstance.resize();
    }
  }

  /**
   * 生成随机数据的方法
   * @returns 返回一个包含日期和随机值的对象
   */
  private randomData() {
    // 获取当前日期并增加一分钟
    const now = new Date(new Date(this.chartData[this.chartData.length - 1].values[0].t).getTime() + 60 * 1000);
    const value = this.chartData[this.chartData.length - 1].values[0].v + Math.random() * 21 - 10;
    return {
      t: now.toString(),
      v: value,
      label: '0'
    };
  }

  /**
   * 生成ECharts配置选项
   */
  private generateEChartsOption(): any {
    const { chart, xAxis, yAxis, series, tooltip, legend, grid, toolbox, dataZoom, animation, backgroundColor, textStyle } = this.chartConfig;

    // 获取x轴数据（时间数据）
    const xAxisData = this.getXAxisData();

    return {
      title: chart.title,
      tooltip: tooltip || {
        trigger: 'axis',
        axisPointer: {
          type: 'cross'
        }
      },
      legend: legend || {
        data: series.map(s => s.name)
      },
      grid: grid || {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true
      },
      toolbox: toolbox,
      dataZoom: dataZoom,
      xAxis: {
        ...xAxis,
        data: xAxisData
      },
      yAxis: yAxis,
      series: this.generateSeriesData(series, xAxisData).filter((s, index) =>
        this.chartData[index]?.active !== false
      ),
      animation: animation,
      backgroundColor: backgroundColor,
      textStyle: textStyle
    };
  }

  /**
   * 获取x轴数据
   */
  private getXAxisData(): string[] {
    if (!this.chartData.length) return [];

    // 使用第一个有效数据源的时间数据作为x轴
    const firstData = this.chartData.find(item => item.values && item.values.length);
    if (!firstData) return [];

    return firstData.values.map(item =>
      new Date(item[this.chartConfig.data.mapping.xAxis]).toLocaleString()
    );
  }

  /**
   * 生成series数据
   */
  private generateSeriesData(seriesConfig: any[], xAxisData: string[]): any[] {
    return seriesConfig.map((s, index) => {
      const seriesMapping = this.chartConfig.data.mapping.series[index];
      if (!seriesMapping) return { ...s, data: [] };

      // 找到对应的数据源 - 使用索引来匹配数据源
      // 如果索引超出chartData范围，使用第一个数据源
      const dataSource = index < this.chartData.length ? this.chartData[index] : this.chartData[0];

      if (!dataSource || !dataSource.values) return { ...s, data: [] };

      // 创建数据点数组，确保与x轴数据对齐
      const seriesData = [];
      const field = seriesMapping.field;

      // 根据x轴数据长度创建对应的数据点
      for (let i = 0; i < xAxisData.length; i++) {
        if (i < dataSource.values.length) {
          // 找到对应时间点的数据
          const dataPoint = dataSource.values[i];
          if (dataPoint && field in dataPoint) {
            seriesData.push(dataPoint[field]);
          } else {
            seriesData.push(null);
          }
        } else {
          seriesData.push(null); // 填充null以保持数据长度一致
        }
      }

      return {
        ...s,
        data: seriesData
      };
    });
  }

  /**
   * 更新图表选项
   */
  public updateChartOptions(): void {
    if (!this.chartInstance) return;

    const option = this.generateEChartsOption();


    this.chartInstance.setOption(option, true);
  }

  /**
   * 从API获取数据
   */
  private async fetchDataFromAPI(): Promise<void> {
    const { endpoint, auth } = this.chartConfig.data.source;

    if (!endpoint) {
      console.error('API端点未配置');
      return;
    }

    try {
      const params: ifs.I_qryDataReq = {
        ecCodes: [endpoint],
        beginTime: '2025/9/11 10:41:26',
        endTime: new Date().toLocaleString(),
        pageNo: 1,
        pageSize: 999
      };

      const res = await Tsrv.getQueryData(params);
      if (typeof res === 'boolean' || Tsrv.noValue(res)) return;

      const data = res.getReturnData('data');
      // value: {'my093': total: 13756, recErrs: null, d: [{t: '2025-07-26T00:48:33.929Z', v: 200, label: '0'}]}

      // const data = await response.json();
      // this.updateData(data);

    } catch (error) {
      console.error('获取API数据失败:', error);
      // 可以在这里实现错误处理逻辑，比如重试机制
    }
  }

  /**
   * 从数据库获取数据（预留接口）
   */
  private async fetchDataFromDatabase(): Promise<void> {
    // 这里预留数据库查询接口
    // 用户可以根据自己的数据库实现这里
    console.warn('数据库数据获取功能需要用户自行实现');
  }

  /**
   * 启动数据刷新任务
   */
  private startDataRefreshTask(): void {
    const interval = this.chartConfig.data.source.refreshInterval;

    if (interval > 0) {
      this.refreshTimer = setInterval(() => {
        this.refresh();
      }, interval);
    }
  }

  /**
   * 停止数据刷新任务
   */
  private stopDataRefreshTask(): void {
    if (this.refreshTimer) {
      clearInterval(this.refreshTimer);
      this.refreshTimer = null;
    }
  }

  // 新增降采样方法
  public downsampleData(data: ifs.I_codeData['d'], interval: number) {
    if (!data || data.length === 0) return [];

    // 按时间排序
    const sortedData = data.sort(
      (a, b) => new Date(a.t).getTime() - new Date(b.t).getTime()
    );

    // 按指定间隔分组
    const grouped = Tsrv.utils.groupBy(sortedData, item => {
      // 将时间戳转换成本地时间
      const date = new Date(item.t).toLocaleString();
      const timestamp = new Date(date).getTime();
      return Math.floor(timestamp / interval) * interval;
    });
    // 处理每组数据
    return Object.values(grouped).map(group => {
      const values = group.map(item => item.v);
      // 保留两位小数
      const avg = Math.round(Tsrv.utils.mean(values) * 100) / 100;

      return {
        t: group[0].t,
        v: avg,
        label: group[0].label
      };
    });
  }

  /**
   * 处理窗口大小变化
   */
  private handleResize(): void {
    this.resize();
  }

  public getTcmd(): T_cmd {
    return this;
  }
}

interface I_cmd extends T_cmd { }
export { I_cmd, T_cmd };
